<template>
  <div class="code-editor">
    <div class="editor-header">
      <div class="header-left">
        <span class="language-label">{{ languageDisplay }}</span>
        <el-select 
          v-model="selectedLanguage" 
          size="small" 
          style="width: 120px"
          @change="handleLanguageChange"
        >
          <el-option label="Java" value="java" />
          <el-option label="Python" value="python" />
          <el-option label="JavaScript" value="javascript" />
          <el-option label="TypeScript" value="typescript" />
          <el-option label="C++" value="cpp" />
          <el-option label="Go" value="go" />
          <el-option label="HTML" value="html" />
          <el-option label="CSS" value="css" />
          <el-option label="SQL" value="sql" />
          <el-option label="其他" value="text" />
        </el-select>
      </div>
      <div class="header-right">
        <el-button 
          text 
          size="small" 
          @click="formatCode"
          title="格式化代码"
        >
          <el-icon><MagicStick /></el-icon>
        </el-button>
        <el-button 
          text 
          size="small" 
          @click="clearCode"
          title="清空"
        >
          <el-icon><Delete /></el-icon>
        </el-button>
        <el-button 
          text 
          size="small" 
          @click="pasteCode"
          title="粘贴"
        >
          <el-icon><DocumentCopy /></el-icon>
        </el-button>
      </div>
    </div>
    
    <div class="editor-container">
      <textarea
        ref="editorRef"
        v-model="codeContent"
        :placeholder="placeholder"
        :style="{ height: `${height}px` }"
        @input="handleInput"
        @keydown="handleKeyDown"
        @scroll="handleScroll"
        class="code-textarea"
        spellcheck="false"
        autocomplete="off"
        autocorrect="off"
        autocapitalize="off"
      ></textarea>
      
      <!-- 语法高亮层 -->
      <div 
        ref="highlightRef"
        class="highlight-layer"
        :style="{ height: `${height}px` }"
      >
        <pre><code :class="`language-${selectedLanguage}`" v-html="highlightedCode"></code></pre>
      </div>
      
      <!-- 行号 -->
      <div class="line-numbers" :style="{ height: `${height}px` }">
        <div 
          v-for="lineNumber in lineCount" 
          :key="lineNumber"
          class="line-number"
        >
          {{ lineNumber }}
        </div>
      </div>
    </div>
    
    <!-- 底部工具栏 -->
    <div class="editor-footer">
      <div class="footer-left">
        <span class="stats">
          行: {{ currentLine }} | 列: {{ currentColumn }} | 字符: {{ codeContent.length }}
        </span>
      </div>
      <div class="footer-right">
        <el-button 
          v-if="showSubmitButton"
          type="primary" 
          size="small" 
          @click="submitCode"
          :disabled="!codeContent.trim()"
        >
          提交代码
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { MagicStick, Delete, DocumentCopy } from '@element-plus/icons-vue'
import hljs from 'highlight.js'

interface Props {
  modelValue: string
  language: string
  height?: number
  placeholder?: string
  showSubmitButton?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  height: 200,
  placeholder: '请输入代码...',
  showSubmitButton: true
})

const emit = defineEmits<{
  'update:modelValue': [value: string]
  'submit': [code: string, language: string]
  'language-change': [language: string]
}>()

// 响应式数据
const editorRef = ref<HTMLTextAreaElement>()
const highlightRef = ref<HTMLElement>()
const codeContent = ref(props.modelValue)
const selectedLanguage = ref(props.language)
const currentLine = ref(1)
const currentColumn = ref(1)

// 计算属性
const languageDisplay = computed(() => {
  const languageMap: Record<string, string> = {
    'javascript': 'JavaScript',
    'typescript': 'TypeScript',
    'java': 'Java',
    'python': 'Python',
    'cpp': 'C++',
    'go': 'Go',
    'html': 'HTML',
    'css': 'CSS',
    'sql': 'SQL',
    'text': '纯文本'
  }
  return languageMap[selectedLanguage.value] || selectedLanguage.value.toUpperCase()
})

const lineCount = computed(() => {
  return Math.max(codeContent.value.split('\n').length, 1)
})

const highlightedCode = computed(() => {
  if (!codeContent.value.trim()) return ''
  
  try {
    if (hljs.getLanguage(selectedLanguage.value)) {
      return hljs.highlight(codeContent.value, { language: selectedLanguage.value }).value
    } else {
      return hljs.highlightAuto(codeContent.value).value
    }
  } catch (error) {
    console.error('代码高亮失败:', error)
    return escapeHtml(codeContent.value)
  }
})

// 方法
const handleInput = (event: Event) => {
  const target = event.target as HTMLTextAreaElement
  codeContent.value = target.value
  emit('update:modelValue', target.value)
  updateCursorPosition()
}

const handleKeyDown = (event: KeyboardEvent) => {
  const target = event.target as HTMLTextAreaElement
  
  // Tab键处理
  if (event.key === 'Tab') {
    event.preventDefault()
    const start = target.selectionStart
    const end = target.selectionEnd
    const spaces = '  ' // 2个空格作为缩进
    
    codeContent.value = codeContent.value.substring(0, start) + spaces + codeContent.value.substring(end)
    emit('update:modelValue', codeContent.value)
    
    nextTick(() => {
      target.selectionStart = target.selectionEnd = start + spaces.length
      updateCursorPosition()
    })
  }
  
  // 自动括号匹配
  if (event.key === '(' || event.key === '[' || event.key === '{') {
    const closingBracket = event.key === '(' ? ')' : event.key === '[' ? ']' : '}'
    const start = target.selectionStart
    const end = target.selectionEnd
    
    if (start === end) { // 没有选中文本
      event.preventDefault()
      codeContent.value = codeContent.value.substring(0, start) + event.key + closingBracket + codeContent.value.substring(end)
      emit('update:modelValue', codeContent.value)
      
      nextTick(() => {
        target.selectionStart = target.selectionEnd = start + 1
        updateCursorPosition()
      })
    }
  }
  
  // Ctrl+Enter 提交代码
  if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
    event.preventDefault()
    submitCode()
  }
}

const handleScroll = () => {
  // 同步高亮层滚动
  if (highlightRef.value && editorRef.value) {
    highlightRef.value.scrollTop = editorRef.value.scrollTop
    highlightRef.value.scrollLeft = editorRef.value.scrollLeft
  }
  updateCursorPosition()
}

const handleLanguageChange = (language: string) => {
  selectedLanguage.value = language
  emit('language-change', language)
}

const updateCursorPosition = () => {
  if (!editorRef.value) return
  
  const textarea = editorRef.value
  const text = textarea.value.substring(0, textarea.selectionStart)
  const lines = text.split('\n')
  
  currentLine.value = lines.length
  currentColumn.value = lines[lines.length - 1].length + 1
}

const formatCode = () => {
  // 简单的代码格式化
  if (!codeContent.value.trim()) {
    ElMessage.warning('没有代码可以格式化')
    return
  }
  
  try {
    let formatted = codeContent.value
    
    // 基本的格式化规则
    if (selectedLanguage.value === 'javascript' || selectedLanguage.value === 'typescript') {
      // JavaScript/TypeScript 格式化
      formatted = formatJavaScript(formatted)
    } else if (selectedLanguage.value === 'java') {
      // Java 格式化
      formatted = formatJava(formatted)
    } else if (selectedLanguage.value === 'python') {
      // Python 格式化
      formatted = formatPython(formatted)
    }
    
    if (formatted !== codeContent.value) {
      codeContent.value = formatted
      emit('update:modelValue', formatted)
      ElMessage.success('代码格式化完成')
    } else {
      ElMessage.info('代码已经是格式化的')
    }
  } catch (error) {
    ElMessage.error('格式化失败')
  }
}

const clearCode = () => {
  codeContent.value = ''
  emit('update:modelValue', '')
  if (editorRef.value) {
    editorRef.value.focus()
  }
}

const pasteCode = async () => {
  try {
    const text = await navigator.clipboard.readText()
    if (text) {
      codeContent.value = text
      emit('update:modelValue', text)
      ElMessage.success('代码已粘贴')
    }
  } catch (error) {
    ElMessage.error('粘贴失败')
  }
}

const submitCode = () => {
  if (!codeContent.value.trim()) {
    ElMessage.warning('请输入代码')
    return
  }
  
  emit('submit', codeContent.value, selectedLanguage.value)
}

// 格式化函数
const formatJavaScript = (code: string): string => {
  // 简单的JavaScript格式化
  return code
    .replace(/\s*{\s*/g, ' {\n  ')
    .replace(/;\s*}/g, ';\n}')
    .replace(/,\s*/g, ', ')
    .replace(/\s*=\s*/g, ' = ')
}

const formatJava = (code: string): string => {
  // 简单的Java格式化
  return code
    .replace(/\s*{\s*/g, ' {\n    ')
    .replace(/;\s*}/g, ';\n}')
    .replace(/,\s*/g, ', ')
    .replace(/\s*=\s*/g, ' = ')
}

const formatPython = (code: string): string => {
  // Python格式化（主要是空格规范化）
  return code
    .replace(/\s*=\s*/g, ' = ')
    .replace(/,\s*/g, ', ')
    .replace(/:\s*/g, ': ')
}

const escapeHtml = (text: string): string => {
  const div = document.createElement('div')
  div.textContent = text
  return div.innerHTML
}

// 监听器
watch(() => props.modelValue, (newValue) => {
  if (newValue !== codeContent.value) {
    codeContent.value = newValue
  }
})

watch(() => props.language, (newLanguage) => {
  selectedLanguage.value = newLanguage
})

// 生命周期
onMounted(() => {
  if (editorRef.value) {
    editorRef.value.focus()
  }
  
  // 初始化语法高亮
  if (typeof hljs !== 'undefined') {
    hljs.configure({ 
      languages: ['javascript', 'typescript', 'java', 'python', 'cpp', 'go', 'html', 'css', 'sql']
    })
  }
})

onUnmounted(() => {
  // 清理事件监听器
})
</script>

<style scoped>
.code-editor {
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
  font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
}

.editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: #fafafa;
  border-bottom: 1px solid #d9d9d9;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.language-label {
  font-size: 12px;
  color: #666;
  font-weight: 500;
}

.header-right {
  display: flex;
  gap: 4px;
}

.editor-container {
  position: relative;
  overflow: hidden;
}

.code-textarea {
  position: absolute;
  top: 0;
  left: 40px; /* 为行号留出空间 */
  right: 0;
  bottom: 0;
  width: calc(100% - 40px);
  padding: 12px;
  border: none;
  outline: none;
  resize: none;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
  background: transparent;
  color: transparent; /* 隐藏原始文本，显示高亮层 */
  caret-color: #333; /* 保持光标可见 */
  white-space: pre;
  overflow: auto;
  z-index: 2;
}

.highlight-layer {
  position: absolute;
  top: 0;
  left: 40px;
  right: 0;
  bottom: 0;
  width: calc(100% - 40px);
  padding: 12px;
  pointer-events: none;
  overflow: hidden;
  z-index: 1;
}

.highlight-layer pre {
  margin: 0;
  padding: 0;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
  background: transparent;
  white-space: pre;
}

.highlight-layer code {
  background: transparent;
  padding: 0;
  font-family: inherit;
}

.line-numbers {
  position: absolute;
  top: 0;
  left: 0;
  width: 40px;
  background: #f5f5f5;
  border-right: 1px solid #e8e8e8;
  padding: 12px 0;
  overflow: hidden;
  user-select: none;
  z-index: 3;
}

.line-number {
  height: 19.5px; /* 与代码行高匹配 */
  font-size: 12px;
  line-height: 19.5px;
  color: #999;
  text-align: right;
  padding-right: 8px;
}

.editor-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 12px;
  background: #fafafa;
  border-top: 1px solid #d9d9d9;
  font-size: 12px;
}

.stats {
  color: #666;
}

/* 语法高亮样式 */
:deep(.hljs) {
  background: transparent !important;
  padding: 0 !important;
}

:deep(.hljs-keyword) {
  color: #d73a49 !important;
  font-weight: 600;
}

:deep(.hljs-string) {
  color: #032f62 !important;
}

:deep(.hljs-comment) {
  color: #6a737d !important;
  font-style: italic;
}

:deep(.hljs-number) {
  color: #005cc5 !important;
}

:deep(.hljs-function) {
  color: #6f42c1 !important;
}

:deep(.hljs-class) {
  color: #e36209 !important;
  font-weight: 600;
}

:deep(.hljs-variable) {
  color: #e36209 !important;
}

:deep(.hljs-built_in) {
  color: #005cc5 !important;
}

:deep(.hljs-type) {
  color: #d73a49 !important;
}

:deep(.hljs-literal) {
  color: #005cc5 !important;
}

:deep(.hljs-params) {
  color: #24292e !important;
}

:deep(.hljs-meta) {
  color: #6f42c1 !important;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .editor-header {
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }
  
  .header-left, .header-right {
    justify-content: space-between;
  }
  
  .code-textarea, .highlight-layer {
    font-size: 12px;
  }
  
  .line-numbers {
    width: 35px;
  }
  
  .code-textarea, .highlight-layer {
    left: 35px;
    width: calc(100% - 35px);
  }
}

/* 焦点状态 */
.code-editor:focus-within {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

/* 滚动条样式 */
.code-textarea::-webkit-scrollbar,
.highlight-layer::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.code-textarea::-webkit-scrollbar-track,
.highlight-layer::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.code-textarea::-webkit-scrollbar-thumb,
.highlight-layer::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.code-textarea::-webkit-scrollbar-thumb:hover,
.highlight-layer::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>
